package server;

import server.mapper.Context;
import server.mapper.Mapper;
import server.mapper.Wrapper;
import java.io.InputStream;
import java.net.Socket;

/**
 * 请求处理类
 */
public class RequestProcessor extends Thread {

    /**
     * 套接字对象
     */
    private Socket socket;

    /**
     * 映射实体对象
     */
    private Mapper mapper;

    public RequestProcessor(Socket socket, Mapper mapper) {
        this.socket = socket;
        this.mapper = mapper;
    }

    @Override
    public void run() {
        try{
            InputStream inputStream = socket.getInputStream();
            //封装Request对象和Response对象
            Request request = new Request(inputStream);
            Response response = new Response(socket.getOutputStream());
            //请求URL
            String url = request.getUrl();
            String[] urlArr = url.split("/");
            //根据URL匹配资源
            Servlet servlet = getServletByUrl(urlArr, mapper);
            //静态资源处理
            if (servlet == null) {
                response.outputHtml(urlArr, mapper);
            } else  {
                //动态资源servlet请求
                //执行servlet
                HttpServlet httpServlet = (HttpServlet) servlet;
                httpServlet.service(request, response);
            }
            socket.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据url获得动态资源servlet的方法
     * @param urlArr 分割后的url
     * @param mapper 映射实体对象
     */
    private Servlet getServletByUrl(String[] urlArr, Mapper mapper) {
        //1.获得Context
        Context context = StaticResourceUtil.getContext(urlArr, this.mapper);
        //2.根据资源名匹配Wrapper中的资源并返回
        if(context == null || context.getWrapperList() == null || context.getWrapperList().size() == 0) return null;
        for (int k = 0; k < context.getWrapperList().size(); k++) {
            Wrapper wrapper = context.getWrapperList().get(k);
            if(wrapper.getUrlPatten().equals("/"+urlArr[2])) {
                return wrapper.getServlet();
            }
        }
        return null;
    }
}
